package com.patternity.model;

import java.util.HashMap;
import java.util.Map;

/**
 * Represents a declaration of some design decision or intent, typically a
 * pattern or idiom
 * 
 * @author Cyrille.Martraire
 */
public class DesignDeclaration {

	/**
	 * The name of the design decision
	 */
	private final String name;

	/**
	 * The site of this declaration (class, package, method...)
	 */
	private final String site;

	/**
	 * Any attribute explicitly specified as part of the declaration
	 */
	private final Map<String, Object> attributes = new HashMap<String, Object>();

	public DesignDeclaration(final String site, final String name,
			final String key, final Object value) {
		this(site, name);
		attributes.put(key, value);
	}

	public DesignDeclaration(final String site, final String name,
			final Map<String, Object> attributes) {
		this(site, name);
		if (attributes != null) {
			this.attributes.putAll(attributes);
		}
	}

	public DesignDeclaration(final String site, final String name) {
		this.site = site;
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public String getSite() {
		return site;
	}

	public Map<String, Object> getAttributes() {
		return attributes;
	}

	public Object getValue(final String key) {
		return attributes.get(key);
	}

	@Override
	public int hashCode() {
		return attributes.hashCode() * name.hashCode() ^ site.hashCode();
	}

	@Override
	public boolean equals(final Object obj) {
		if (this == obj) {
			return true;
		}
		final DesignDeclaration other = (DesignDeclaration) obj;
		return attributes.equals(other.attributes) && name.equals(other.name)
				&& site.equals(other.site);
	}

	@Override
	public String toString() {
		return name + " site: " + site + " " + attributes;
	}
}